import type {
  ComputeContext,
  CreateCrudOptionsProps,
  CreateCrudOptionsRet,
  CrudExpose,
  ScopeContext,
} from '@fast-crud/fast-crud';

import type { Ref } from 'vue';

import type { ExtendedModalApi } from '@vben/common-ui';
import type { Undefinedable } from '@vben/types';

import type { FormRulesExt } from '#/api';
import type { ExtendMsgTemplateModel } from '#/api/basic/msg/model/extendMsgTemplateModel';
import type { ActionEnum } from '#/enums/commonEnum';

import { h, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';

import { useAccess } from '@vben/access';
import { $t } from '@vben/locales';

import { java } from '@codemirror/lang-java';
import { oneDark } from '@codemirror/theme-one-dark';
import { compute } from '@fast-crud/fast-crud';

import { ExtendMsgTemplateApi } from '#/api/basic/msg/extendMsgTemplate';
import { MsgTemplateTypeEnum } from '#/enums/base';
import { DictEnum } from '#/enums/commonEnum';
import { PermCode } from '#/enums/perm';
import {
  backendDict,
  createdTimeColumn,
  deleteButton,
  indexColumn,
  STATE_CONSTANT_DICT,
  YES_NO_CONSTANT_DICT,
} from '#/plugins/fast-crud/common';

const logExtensions = [java(), oneDark];
const { hasPermission } = useAccess();
const permCode = PermCode.basic.msg.template;

type ContextRef = {
  defMsgTemplateRef: Ref<Undefinedable<ExtendedModalApi>>;
};

export function createCrudOptions(
  props: CreateCrudOptionsProps<
    ExtendMsgTemplateModel.ExtendMsgTemplateResultVO,
    ContextRef
  >,
): CreateCrudOptionsRet<ExtendMsgTemplateModel.ExtendMsgTemplateResultVO> {
  const selectedRowKeys = ref<string[]>([]);

  return {
    crudOptions: {
      request: {
        pageRequest: ExtendMsgTemplateApi.pageRequest,
        addRequest: ExtendMsgTemplateApi.addRequest,
        editRequest: ExtendMsgTemplateApi.editRequest,
        delRequest: ExtendMsgTemplateApi.delRequest,
        infoRequest: ExtendMsgTemplateApi.infoRequest,
      },
      actionbar: {
        buttons: {
          add: { show: false },
          import: {
            text: $t('common.title.import'),
            click() {
              props.context?.defMsgTemplateRef.value?.setData({});
              props.context?.defMsgTemplateRef.value?.open();
            },
          },
          ...deleteButton({
            crudExpose: props.crudExpose,
            selectedRowKeys,
            removeFn: ExtendMsgTemplateApi.remove,
            role: permCode.delete,
          }),
        },
      },
      table: {
        striped: true,
        rowKey: 'id',
        rowSelection: {
          type: 'checkbox',
          selectedRowKeys,
          onChange: (changed: string[]) => {
            selectedRowKeys.value = changed;
          },
        },
      },
      rowHandle: {
        width: '200px',
        buttons: {
          edit: { show: hasPermission(permCode.edit) },
          remove: { show: hasPermission(permCode.delete) },
          copy: { show: false },
        },
      },
      columns: {
        ...indexColumn(props.crudExpose),
        state: {
          title: $t('devOperation.ops.defMsgTemplate.state'),
          type: 'dict-radio',
          dict: STATE_CONSTANT_DICT,
          search: { show: true },
          addForm: { value: true },
          column: { width: 120 },
          form: {
            component: {
              optionName: 'a-radio-button',
            },
          },
        },
        code: {
          title: $t('devOperation.ops.defMsgTemplate.code'),
          type: 'text',
          search: { show: true },
        },
        name: {
          title: $t('devOperation.ops.defMsgTemplate.name'),
          type: 'text',
          search: { show: true },
        },
        title: {
          title: $t('devOperation.ops.defMsgTemplate.title'),
          type: 'text',
          column: { show: false },
        },
        content: {
          title: $t('devOperation.ops.defMsgTemplate.content'),
          type: 'text',
          viewForm: { ignoreUseCellComponent: true },
          form: {
            col: { span: 24 },
            render: (
              scope: ScopeContext<ExtendMsgTemplateModel.ExtendMsgTemplateResultVO>,
            ) => {
              return h(Codemirror, {
                autofocus: true,
                extensions: logExtensions,
                indentWithTab: true,
                style: { height: '200px' },
                tabSize: 2,
                placeholder: 'groovy 脚本',
                modelValue: scope.form.content,
                'onUpdate:modelValue': (newValue) => {
                  scope.form.content = newValue;
                },
              });
            },
          },
          column: { show: false },
        },
        script: {
          title: $t('devOperation.ops.defMsgTemplate.script'),
          type: 'text',
          viewForm: { ignoreUseCellComponent: true },
          form: {
            col: { span: 24 },
            render: (
              scope: ScopeContext<ExtendMsgTemplateModel.ExtendMsgTemplateResultVO>,
            ) => {
              return h(Codemirror, {
                autofocus: true,
                placeholder: 'Freemarker 脚本',
                extensions: logExtensions,
                indentWithTab: true,
                style: { height: '200px' },
                tabSize: 2,
                modelValue: scope.form.script,
                'onUpdate:modelValue': (newValue: any) => {
                  scope.form.script = newValue;
                },
              });
            },
          },
          column: { show: false },
        },
        remarks: {
          title: $t('devOperation.ops.defMsgTemplate.remarks'),
          type: 'textarea',
          form: { col: { span: 24 } },
          column: { show: false },
        },
        sign: {
          title: $t('devOperation.ops.defMsgTemplate.sign'),
          type: 'text',
          form: {
            show: compute(
              (
                context: ComputeContext<ExtendMsgTemplateModel.ExtendMsgTemplateResultVO>,
              ) => {
                return context.form?.type === MsgTemplateTypeEnum.SMS;
              },
            ),
          },
          column: { show: false },
        },
        templateCode: {
          title: $t('devOperation.ops.defMsgTemplate.templateCode'),
          type: 'text',
          form: {
            show: compute(
              (
                context: ComputeContext<ExtendMsgTemplateModel.ExtendMsgTemplateResultVO>,
              ) => {
                return context.form?.type === MsgTemplateTypeEnum.SMS;
              },
            ),
          },
          column: { show: false },
        },
        target: {
          title: $t('devOperation.ops.defMsgTemplate.target'),
          type: 'dict-radio',
          dict: backendDict(DictEnum.EchoDictType_Base_NOTICE_TARGET),
          column: { show: false },
          form: {
            show: compute(
              (
                context: ComputeContext<ExtendMsgTemplateModel.ExtendMsgTemplateResultVO>,
              ) => {
                return context.form?.type === MsgTemplateTypeEnum.NOTICE;
              },
            ),
            component: {
              optionName: 'a-radio-button',
            },
          },
        },
        autoRead: {
          title: $t('devOperation.ops.defMsgTemplate.autoRead'),
          type: 'dict-radio',
          dict: YES_NO_CONSTANT_DICT,
          addForm: { value: true },
          form: {
            show: compute(
              (
                context: ComputeContext<ExtendMsgTemplateModel.ExtendMsgTemplateResultVO>,
              ) => {
                return context.form?.type === MsgTemplateTypeEnum.NOTICE;
              },
            ),
            component: {
              optionName: 'a-radio-button',
            },
          },
          column: { show: false },
        },
        remindMode: {
          title: $t('devOperation.ops.defMsgTemplate.remindMode'),
          type: 'dict-radio',
          dict: backendDict(DictEnum.NoticeRemindModeEnum),
          form: {
            show: compute(
              (
                context: ComputeContext<ExtendMsgTemplateModel.ExtendMsgTemplateResultVO>,
              ) => {
                return context.form?.type === MsgTemplateTypeEnum.NOTICE;
              },
            ),
            component: {
              optionName: 'a-radio-button',
            },
          },
          column: { show: false },
        },
        url: {
          title: $t('devOperation.ops.defMsgTemplate.url'),
          type: 'text',
          form: {
            show: compute(
              (
                context: ComputeContext<ExtendMsgTemplateModel.ExtendMsgTemplateResultVO>,
              ) => {
                return context.form?.type === MsgTemplateTypeEnum.NOTICE;
              },
            ),
          },
          column: { show: false },
        },
        ...createdTimeColumn({}),
      },
    },
  };
}

export const frontRules = (
  _crudExpose: CrudExpose,
  _mode: ActionEnum,
): FormRulesExt => {
  return {};
};
